/*
 * VoltageTrace.cc
 *
 * @created Apr 19, 2013
 * @author Tim Niggemann, III Phys. Inst. A, RWTH Aachen University
 * @copyright GNU General Public License v3.0
 */

#include "digi/G4SipmVoltageTraceDigi.hh"

#include <math.h>

G4ThreadLocal G4Allocator<G4SipmVoltageTraceDigi> *G4SipmVoltageTraceDigiAllocator = 0;
// 构造函数，初始化G4SipmVoltageTraceDigi对象，设置了SiPM的标识符、时间范围、时间bin宽度、精度和电压范围，并创建了一个向量来存储每个时间bin的电压值（初始化为0.0）。
G4SipmVoltageTraceDigi::G4SipmVoltageTraceDigi(const G4SipmId _sipmId, const double _tMin, const double _tMax,
											   const double _timeBinWidth) : sipmId(_sipmId), tMin(_tMin), tMax(_tMax), timeBinWidth(_timeBinWidth), precision(12), voltageRange(2. * CLHEP::volt)
{
	size_t n = ceil((tMax - tMin) / timeBinWidth);
	voltages = std::vector<double>(n, 0.);
}

G4SipmVoltageTraceDigi::~G4SipmVoltageTraceDigi()
{
	//
}
// 拷贝构造函数，用于创建一个新的G4SipmVoltageTraceDigi对象作为现有对象的副本。
const G4SipmVoltageTraceDigi &G4SipmVoltageTraceDigi::operator=(const G4SipmVoltageTraceDigi &right)
{
	tMin = right.getTMin();
	tMax = right.getTMax();
	timeBinWidth = right.getTimeBinWidth();
	precision = right.getPrecision();
	voltageRange = right.getVoltageRange();
	voltages = right.getContainer();
	return *this;
}
// 重载等号操作符，用于比较两个G4SipmVoltageTraceDigi对象是否相等。
int G4SipmVoltageTraceDigi::operator==(const G4SipmVoltageTraceDigi &right) const
{
	return tMin == right.getTMin() && tMax == right.getTMax() && timeBinWidth == right.getTimeBinWidth() && precision == right.getPrecision() && voltageRange == right.getVoltageRange() && voltages == right.getContainer();
}
// 获取精度值。
int G4SipmVoltageTraceDigi::getPrecision() const
{
	return precision;
}
// 设置精度值。
void G4SipmVoltageTraceDigi::setPrecision(int _precision)
{
	precision = _precision;
}
// 获取时间bin宽度。
double G4SipmVoltageTraceDigi::getTimeBinWidth() const
{
	return timeBinWidth;
}
// 获取时间范围的最大值。
double G4SipmVoltageTraceDigi::getTMax() const
{
	return tMax;
}
// 获取时间范围的最小值。
double &G4SipmVoltageTraceDigi::at(size_t i)
{
	return voltages.at(i);
}
// 获取测量后的电压值，通过将原始电压乘以因子并四舍五入到指定精度来近似表示。
double G4SipmVoltageTraceDigi::atMeasured(size_t i) const
{
	double factor = pow(2, precision) / voltageRange;
	return round(voltages.at(i) * factor) / factor;
}
// 获取电压范围。
double G4SipmVoltageTraceDigi::getVoltageRange() const
{
	return voltageRange;
}
// 获取特定时间bin的索引，通过将给定时间减去最小时间并除以时间bin宽度来计算。
size_t G4SipmVoltageTraceDigi::index(const double t) const
{
	return round((t - tMin) / timeBinWidth);
}
// 获取电压向量的大小。
size_t G4SipmVoltageTraceDigi::size() const
{
	return voltages.size();
}
// 获取特定索引对应的时间值，通过将索引乘以时间bin宽度并加上最小时间来计算。
double G4SipmVoltageTraceDigi::time(const size_t i) const
{
	return i * timeBinWidth + tMin;
}
// 设置电压范围。
void G4SipmVoltageTraceDigi::setVoltageRange(double _voltageRange)
{
	voltageRange = _voltageRange;
}
// 获取时间范围的最小值。
double G4SipmVoltageTraceDigi::getTMin() const
{
	return tMin;
}
// 获取SiPM的标识符。
G4SipmId G4SipmVoltageTraceDigi::getSipmId() const
{
	return sipmId;
}
// 获取电压向量。
std::vector<double> G4SipmVoltageTraceDigi::getContainer() const
{
	return voltages;
}
